Vamos para um pouco de código o/

Imports

In [1]:
%matplotlib inline
import collections
import cv2
import dlib
from imutils import face_utils
from matplotlib import pyplot as plt
import numpy as np

# from google.colab.patches import cv2_imshow

Códigos!!!

Dlib detecção de rosto

Preparativos...

In [10]:
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('helpers/'
                                 'shape_predictor_68_face_landmarks.dat')

O poder do Dlib

In [11]:
image_01 = cv2.imread('persons/bolsonaro.png')
image_01 = cv2.cvtColor(image_01, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(10, 10))
plt.imshow(image_01)
plt.show()

Capturar a região do rosto

In [12]:
face = face_detection(image_01, detector)

plt.figure(figsize=(10, 10))
plt.imshow(face)
plt.show()

Será que continua capturando o rosto se a imagem estiver alterada?

In [13]:
kernel = np.ones((7, 7),np.float32)/25
result_2d_filter = cv2.filter2D(image_01,-1,kernel)

plt.figure(figsize=(10, 10))
plt.imshow(result_2d_filter)
plt.show()
In [14]:
face = face_detection(result_2d_filter, detector)

plt.figure(figsize=(10, 10))
plt.imshow(face)
plt.show()
In [15]:
rows, cols, _ = image_01.shape

M = cv2.getRotationMatrix2D((cols/2,rows/2), 45, 1)
rotate_image_01 = cv2.warpAffine(image_01,M,(cols,rows))

plt.figure(figsize=(10, 10))
plt.imshow(rotate_image_01)
plt.show()
In [16]:
face = face_detection(rotate_image_01, detector)

plt.figure(figsize=(10, 10))
plt.imshow(face)
plt.show()

E se tiver mais de um rosto?

In [17]:
image_02 = cv2.imread('persons/bolsonaro_02.jpg')
image_02 = cv2.cvtColor(image_02, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(10, 10))
plt.imshow(image_02)
plt.show()

Será que ele detecta mesmo todos os rostos?

In [18]:
faces = face_detection(image_02, detector)

plt.figure(figsize=(10, 10))
plt.imshow(faces)
plt.show()

Pontos de interesse do rosto

alt text

Vamos ver esses pontos nas imagens

In [19]:
land = landmarks_detection(image_02, detector, predictor)

plt.figure(figsize=(15, 15))
plt.imshow(land)
plt.show()
In [20]:
land = landmarks_draw(image_02, detector, predictor)

plt.figure(figsize=(10, 10))
plt.imshow(land)
plt.show()

Regiões de interesse do rosto

In [21]:
land = facial_landmarks(image_01, predictor, detector)

plt.figure(figsize=(10, 10))
plt.imshow(land)
plt.show()

Vamos brincar um pouco com essas regiões de interesse... ou tentar.

In [22]:
overlay = image_01.copy()
pts = get_coordinates(image_01, 'mouth', detector, predictor)[0]

for l in range(1, len(pts)):
    ptA = tuple(pts[l - 1])
    ptB = tuple(pts[l])
    cv2.line(overlay, ptA, ptB, (0, 255, 0), 2)
In [23]:
plt.figure(figsize=(10, 10))
plt.imshow(overlay)
plt.show()

Ops... Vamos tentar de novo...

In [24]:
overlay = image_01.copy()
pts = get_coordinates(image_01, 'mouth', detector, predictor)[0]
In [25]:
ptA = tuple(pts[0])  # Canto esquerdo da boca
ptB = tuple(pts[6])  # Canto direito da boca

ptC = tuple(pts[3])  # Canto superior da boca
ptD = tuple(pts[9])  # Canto inferior da boca

h = abs(ptC[1] - ptD[1])
w = abs(ptA[0] - ptB[0])

# img[y:y+h, x:x+w]
new_overlay = overlay[ptA[1]: ptA[1] + h, ptA[0]: ptA[0] + w]
In [26]:
plt.figure(figsize=(10, 10))
plt.imshow(new_overlay)
plt.show()
In [27]:
offset = 20

# img[y:y+h, x:x+w]
new_overlay = overlay[ptA[1] - offset: ptA[1] + h,
                      ptA[0] - offset: ptA[0] + w + offset]
plt.figure(figsize=(10, 10))
plt.imshow(new_overlay)
plt.show()

Que tal um pouco de barba?

In [28]:
sticker = cv2.imread('stickers/barba_02.png', -1)
watermark = cv2.resize(sticker, None, fx=0.4, fy=0.4)

plt.figure(figsize=(10, 10))
plt.imshow(watermark)
plt.show()
In [29]:
frame = cv2.cvtColor(image_01, cv2.COLOR_RGB2BGRA)
frame_h, frame_w, frame_c = frame.shape
In [30]:
overlay = frame.copy()
watermark_h, watermark_w, watermark_c = watermark.shape
In [31]:
for i in range(0, watermark_h):
    for j in range(0, watermark_w):
        if watermark[i, j][3] != 0:
            w_offset = ptB[0] - (w*2)  # ptB é o canto direito da boca
            h_offset = ptD[1] - (int(ptD[1]/5) + offset)  # ptD é o canto inferior da boca
            overlay[h_offset + i, w_offset + j] = watermark[i, j]

overlay = cv2.cvtColor(overlay, cv2.COLOR_BGRA2RGB)
In [32]:
plt.figure(figsize=(10, 10))
plt.imshow(overlay)
plt.show()

Ou um óculos?

In [33]:
stickers = cv2.imread('stickers/oculos_01.png', -1)
watermark = cv2.resize(stickers, None, fx=0.6, fy=0.6)

plt.figure(figsize=(10, 10))
plt.imshow(cv2.cvtColor(watermark, cv2.COLOR_BGRA2RGB))
plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

Precisamos saber onde está os olhos...

In [34]:
overlay = image_01.copy()
pts = get_coordinates(image_01, 'right_eye', detector, predictor)[0]

ptA = tuple(pts[0])  # Canto esquerdo do olho
ptB = tuple(pts[3])  # Canto direito do olho

ptC = tuple(pts[1])  # Canto superior do olho
ptD = tuple(pts[5])  # Canto inferior do olho

h = abs(ptC[1] - ptD[1])
w = abs(ptA[0] - ptB[0])
offset = 30

# img[y:y+h, x:x+w]
overlay = overlay[ptA[1] - offset: ptA[1] + h,
                  ptA[0] - offset: ptA[0] + w + offset]
In [35]:
plt.figure(figsize=(10, 10))
plt.imshow(overlay)
plt.show()

E agora vamos ajudar ele a enxergar melhor :)

In [36]:
frame = cv2.cvtColor(image_01, cv2.COLOR_RGB2BGRA)
frame_h, frame_w, frame_c = frame.shape

# overlay with 4 channels BGR and Alpha
overlay = frame.copy()
watermark_h, watermark_w, watermark_c = watermark.shape

# replace overlay pixels with watermark pixel values
for i in range(0, watermark_h):
    for j in range(0, watermark_w):
        if watermark[i,j][3] != 0:
            w_offset = ptB[0] - (w*3)
            h_offset = ptD[1] - (int(ptD[1]/2) + offset)
            overlay[h_offset + i, w_offset + j] = watermark[i, j]

overlay = cv2.cvtColor(overlay, cv2.COLOR_BGRA2RGB)
In [37]:
plt.figure(figsize=(10, 10))
plt.imshow(overlay)
plt.show()

Vamos testar com outra imagem

In [38]:
image_03 = cv2.imread('persons/barack_obama.jpg')
image_03 = cv2.cvtColor(image_03, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(10, 10))
plt.imshow(image_03)
plt.show()

Vamos usar aquele mesmo óculos

In [39]:
stickers = cv2.imread('stickers/oculos_01.png', -1)
watermark = cv2.resize(stickers, None, fx=1, fy=1)

plt.figure(figsize=(10, 10))
plt.imshow(cv2.cvtColor(watermark, cv2.COLOR_BGRA2RGB))
plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

E vamos capturar a região dos olhos de novo...

In [40]:
overlay = image_03.copy()
pts = get_coordinates(image_03, 'right_eye', detector, predictor)[0]

ptA = tuple(pts[0])  # Canto esquerdo do olho
ptB = tuple(pts[3])  # Canto direito do olho

ptC = tuple(pts[1])  # Canto superior do olho
ptD = tuple(pts[5])  # Canto inferior do olho

h = abs(ptC[1] - ptD[1])
w = abs(ptA[0] - ptB[0])
offset = 30

# img[y:y+h, x:x+w]
overlay = overlay[ptA[1] - offset: ptA[1] + h,
                  ptA[0] - offset: ptA[0] + w + offset]
In [41]:
plt.figure(figsize=(10, 10))
plt.imshow(overlay)
plt.show()

Agora a melhor parte o/

In [42]:
frame = cv2.cvtColor(image_03, cv2.COLOR_RGB2BGRA)
frame_h, frame_w, frame_c = frame.shape

# overlay with 4 channels BGR and Alpha
overlay = frame.copy()
watermark_h, watermark_w, watermark_c = watermark.shape

# replace overlay pixels with watermark pixel values
for i in range(0, watermark_h):
    for j in range(0, watermark_w):
        if watermark[i,j][3] != 0:
            w_offset = ptB[0] - (w*2) - offset
            h_offset = ptD[1] - (int(ptD[1]/2) + offset)
            overlay[h_offset + i, w_offset + j] = watermark[i, j]

overlay = cv2.cvtColor(overlay, cv2.COLOR_BGRA2RGB)
In [43]:
plt.figure(figsize=(10, 10))
plt.imshow(overlay)
plt.show()